import { FundAccountInsideType } from "../engine/common/fundDefinition";
import { CsFundDouble } from "../engine/common/csFundDouble";
import { CsDouble } from "../engine/common/csDouble";
import { Definition } from "../engine/common/definition";
import { Engine } from "../engine/engine";
import { uploadImgFile } from "../network/api";
import { ProgressState, CommonOrderStatus } from "../engine/common/docDefinition";
import {
    PendingReceiveFundSource, ReceiveFundType, ReceiveOverFlowHandleMethod,
    PendingPaymentFundSource, PaymentFundType, PaymentOverFlowHandleMethod

} from "../engine/common/fundDefinition";
import { AppTheme } from "../theme/appTheme";
import { InventoryInOutType } from "../engine/inventory/inventory";
import { TestConfig } from "../engine/common/testConfig";


export class Util {


    static showToast(msg) {
        uni.showToast({
            title: msg,
            icon: 'none',
            //  duration: 1000
        });
    }

    static _scanCodeAsync(options = {}) {

        if (TestConfig.simScanCode) {
            return { result: "6902083881405" };
        } else {
            return new Promise((resolve, reject) => {
                uni.scanCode({
                    ...options,
                    success: resolve,
                    fail: reject
                });
            });
        }
    }

    // 获取出入库类型名称
    static getInventoryInoutTypeName(type) {
        switch (type) {
            case InventoryInOutType.In:
                return "入库";
            case InventoryInOutType.Out:
                return "出库";
            case InventoryInOutType.Init:
                return "期初";
            case InventoryInOutType.Sheet:
                return "盘点";
            default:
                break;
        }
        console.log("未定义的入库类型：" + type);
        return "未知";
    }

    // 扫码二维码
    static async scanQrAndBarCodeAsync() {
        try {
            const res = await Util._scanCodeAsync({
                onlyFromCamera: true,
                scanType: ["barCode", "qrCode"]
            });
            console.log("扫码成功:", res);
            return res.result; // 就是扫码内容
        } catch (err) {
            console.error("扫码失败:", err);
            uni.showToast({
                title: "扫码失败，请重试",
                icon: "none"
            });
            return null;
        }
    }

    /**
     * 判断是否为空
     */
    static isEmpty(value) {
        if (value === null || value === undefined || value === '') {
            return true;
        }
        if (typeof value === 'number') {
            return false;
        }
        //if (typeof value === 'string') {
        //    return value.trim() === '';
        //}
        return false;
    }

    /**
     * Convert a number to a string with specified precision
     * @param {number} num - The number to convert
     * @param {number} precision - The number of decimal places to keep
     * 
     **/
    static convertWithPrecision(num, precision, precisionDown = true) {
        if (typeof num !== 'number' || typeof precision !== 'number') {
            console.log("Invalid input for convertWithPrecision");
            return 0;
        }

        if (precisionDown) {
            // 多保留一位再截断字符串
            let str = num.toFixed(precision + 1);
            let truncatedStr = str.substring(0, str.length - 1);
            return parseFloat(truncatedStr);
        } else {
            return parseFloat(num.toFixed(precision));
        }
    }


    // Amount precision
    static _getFundPrecitionString(num) {
        return num.toFixed(Definition.fundPrecision);
    }

    // Get data with set precision and include currency symbol
    static getFundString(num, { currencyCharector = true, spaceStr = " ", zeroDashLine = false } = {}) {
        // Prevent -0.0

        if (num == null) return '--'

        if (num === -0.0) {
            num = 0;
        }

        if (num === 0 && zeroDashLine) {
            return '--';
        }

        return currencyCharector
            ? (Engine.getCurrencyCharector() + spaceStr + Util._getFundPrecitionString(num))
            : Util._getFundPrecitionString(num);
    }

    // Helper function
    static _decimalString(value, notShowDecimalWhenCountWithoutDecimal, precision) {
        if (notShowDecimalWhenCountWithoutDecimal && Math.trunc(value) === value) {
            return Math.trunc(value).toString();
        } else {
            return value.toFixed(precision || Definition.precision);
        }
    }

    // 转换数量为String
    // count double;  unit MeasurementUnit
    static getCountString(
        count,
        unit,
        {
            withUnitName = false,
            withPrePositiveNegtiveSignal = false,
            notShowDecimalWhenCountWithoutDecimal = true,
            precision = null, // 指定精度
        } = {}
    ) {
        if (count == null) return '--'
        if (count !== null && count !== undefined) {
            const signalPrefix = withPrePositiveNegtiveSignal ? (count > 0 ? "+" : "") : "";

            if (unit && unit.supportDecimal) {
                return signalPrefix +
                    Util._decimalString(count, notShowDecimalWhenCountWithoutDecimal, precision) +
                    (withUnitName ? " " + unit.name : "");
            } else if (unit && !unit.supportDecimal) {
                return signalPrefix +
                    Math.trunc(count).toString() +
                    (withUnitName ? " " + unit.name : "");
            } else {
                return signalPrefix +
                    Util._decimalString(count, notShowDecimalWhenCountWithoutDecimal, precision);
            }
        } else {
            if (unit) {
                return "NA" + (withUnitName ? " " + unit.name : "");
            } else {
                return "NA";
            }
        }
    }

    /**
     * Convert JSON value to string
     * @param {*} value - The value to convert
     * @param {string} [defaultValue=""] - Default value if conversion fails
     * @returns {string} Converted string value
     */
    static jsonToString(value, defaultValue = "") {
        if (value == null) {
            return defaultValue;
        } else {
            let retValue = defaultValue;
            try {
                retValue = String(value);
            } catch (err) {
                console.log(`Convert string failed: ${err}`);
            }
            return retValue;
        }
    }

    /// commodity id 后台命名不统一，容易解析
    /// json 转换为 String
    static jsonCommodityUnitoString(json, defaultValue = "") {
        var value = json['commodityUnitId'] ?? json['commondityUnitId'];

        return Util.jsonToString(value, defaultValue);
    }

    /**
 * 将 JSON 值转换为布尔值
 * @param {*} value - 要转换的值
 * @param {boolean} defaultValue - 转换失败时的默认值
 * @param {string} [subNodeName] - 可选，当 value 是对象时需要提取的子节点名
 * @returns {boolean} 转换后的布尔值
 */
    static jsonToBool(value, defaultValue, subNodeName) {
        if (value == null) {
            return defaultValue;
        }

        try {
            // 处理子节点提取
            const targetValue = subNodeName
                ? value[subNodeName]  // 提取子属性
                : value;             // 直接使用原值

            // If value is already a boolean, return it directly
            if (typeof targetValue === 'boolean') {
                return targetValue;
            }

            // 转换逻辑
            const strVal = String(targetValue).toLowerCase();
            return strVal === '1' || strVal === 'true';

        } catch (err) {
            console.error(`布尔值转换失败: ${err}`);
            return defaultValue;
        }
    }
    /**
     * Convert JSON value to integer
     * @param {*} value - The value to convert
     * @param {number} [defaultValue=0] - Default value if conversion fails
     * @returns {number} Converted integer value
     */
    static jsonToInt(value, defaultValue = 0) {
        if (value == null) {
            return defaultValue;
        } else {
            let retValue = defaultValue;
            try {
                retValue = parseInt(value.toString(), 10);
                if (isNaN(retValue)) {
                    retValue = defaultValue;
                }
            } catch (err) {
                console.log(`Convert failed: ${err}`);
            }
            return retValue;
        }
    }

    static jsonToFundAccountInsideType(jsonValue, defaultValue = FundAccountInsideType.NormalAccount) {
        if (jsonValue == null) {
            return defaultValue;
        }

        try {
            const match = Object.values(FundAccountInsideType).find(
                (type) => type.code === jsonValue
            );
            return match ?? defaultValue;
        } catch (err) {
            console.warn('Convert jsonToFundAccountInsideType failed:', err);
            return defaultValue;
        }
    }

    // json 对象转换为 CsDouble
    // value: json 对象
    // defaultValue: 默认值
    // precision: 指定精度，默认为 -1 表示使用服务器返回的原始精度
    static jsonToCsDouble(value, defaultValue, precision = -1, isFixedPrecision = false) {
        return new CsDouble(Util.jsonToDouble(value, defaultValue), precision, isFixedPrecision);
    }

    // json 对象转换为 CsFundDouble
    // value: json 对象
    // defaultValue: 默认值
    // precision: 指定精度，默认为 -1 表示使用服务器返回的原始精度
    static jsonToCsFundDouble(value, defaultValue, precision = -1) {
        return new CsFundDouble(Util.jsonToDouble(value, defaultValue), precision);
    }

    // json String 对象转换为 Json
    // value: json 对象
    // defaultValue: 默认值
    // precision: 指定精度，默认为 -1 表示使用服务器返回的原始精度
    static jsonStringToJson(value, defaultValue = {}) {
        let ret = defaultValue;
        try {
            let str = Util.jsonToString(value);
            ret = JSON.parse(str) || defaultValue;
            return ret;
        } catch (err) {
            console.log(`Convert json string failed: ${err}`);
        }

        return ret;
    }

    /**
 * json 转换为 String
 * @param {*} value 
 * @param {string} defaultValue 
 * @returns {string}
 */
    static jsonToString(value, defaultValue = "") {
        if (value === null || value === undefined) {
            return defaultValue;
        } else {
            let retValue = defaultValue;
            try {
                retValue = value.toString();
            } catch (err) {
                console.log(`Convert string failed: ${err}`);
            }
            return retValue;
        }
    }

    /**
     * 将 JSON 对象转换为 double
     * @param {any} value - 要转换的值
     * @param {number} defaultValue - 默认值
     * @returns {number} - 转换后的 double 值
     */
    static jsonToDouble(value, defaultValue) {
        if (value == null) {
            return defaultValue;
        } else {
            let retValue = defaultValue;
            try {
                retValue = parseFloat(value);  // 使用 parseFloat 转换为浮动类型
            } catch (err) {
                console.log("Convert failed:", err);
            }

            return retValue;
        }
    }

    /**
 * json 转换为 ProgressState
 * @param {*} jsonValue - The JSON value to convert
 * @param {ProgressState} [defaultValue=ProgressState.None] - Default value if conversion fails
 * @returns {ProgressState} Converted ProgressState value
 */
    static jsonToPorgressState(jsonValue, defaultValue = ProgressState.None) {
        if (jsonValue == null) {
            return defaultValue;
        } else {
            let retValue = defaultValue;
            try {
                retValue = ProgressState.fromCode(jsonValue);
            } catch (err) {
                console.log(`Convert jsonToPorgressState failed: ${err}`);
            }
            return retValue;
        }
    }

    /**
     * json 转换为 PendingReceiveFundSource
     * @param {*} jsonValue - The JSON value to convert
     * @param {PendingReceiveFundSource} [defaultValue=PendingReceiveFundSource.UNKNOWN] - Default value if conversion fails
     * @returns {PendingReceiveFundSource} Converted PendingReceiveFundSource value
     */
    static jsonToPendingReceiveFundSource(jsonValue, defaultValue = PendingReceiveFundSource.UNKNOWN) {
        if (jsonValue == null) {
            return defaultValue;
        } else {
            let retValue = defaultValue;
            try {
                retValue = PendingReceiveFundSource.fromCode[jsonValue];
            } catch (err) {
                console.log(`Convert jsonToPendingReceiveFundSource failed: ${err}`);
            }
            return retValue;
        }
    }



    /// json 转换为found type
    static jsonToReceiveFundType(jsonValue,
        defaultValue = null) {
        if (jsonValue == null) {
            return defaultValue;
        } else {
            let retValue = defaultValue;
            try {
                retValue = ReceiveFundType.fromCode(jsonValue);
            } catch (err) {
                console.log(`Convert jsonToReceiveFundType string failed: ${err}`);
            }
            return retValue;
        }
    }

    /// json 转换为 ReceiveOverFlowHandleMethod
    static jsonToReceiveOverFlowHandleMethod(
        jsonValue,
        { defaultValue = null } = {}) {
        if (jsonValue == null) {
            return defaultValue;
        } else {
            let retValue = defaultValue;
            try {
                retValue = ReceiveOverFlowHandleMethod.fromCode(jsonValue);
            } catch (err) {
                console.log(`Convert jsonToReceiveOverFlowHandleMethod string failed: ${err}`);
            }
            return retValue;
        }
    }

    /**
 * json 转换为 PendingPaymentFundSource
 * @param {*} jsonValue - The JSON value to convert
 * @param {PendingPaymentFundSource} [defaultValue=PendingPaymentFundSource.UNKNOWN] - Default value if conversion fails
 * @returns {PendingPaymentFundSource} Converted PendingPaymentFundSource value
 */
    static jsonToPendingPaymentFundSource(jsonValue, defaultValue = PendingPaymentFundSource.UNKNOWN) {
        if (jsonValue == null) {
            return defaultValue;
        } else {
            let retValue = defaultValue;
            try {
                retValue = PendingPaymentFundSource.fromCode(jsonValue);
            } catch (err) {
                console.log(`Convert jsonToPendingPaymentFundSource failed: ${err}`);
            }
            return retValue;
        }
    }

    /**
     * json 转换为 PaymentFundType
     * @param {*} jsonValue - The JSON value to convert
     * @param {PaymentFundType} defaultValue - Default value if conversion fails
     * @returns {PaymentFundType} Converted PaymentFundType value
     */
    static jsonToPaymentFundType(jsonValue, defaultValue = null) {
        if (jsonValue == null) {
            return defaultValue;
        } else {
            let retValue = defaultValue;
            try {
                retValue = PaymentFundType.fromCode(jsonValue);
            } catch (err) {
                console.log(`Convert jsonToPaymentFundType string failed: ${err}`);
            }
            return retValue;
        }
    }

    /**
     * json 转换为 PaymentOverFlowHandleMethod
     * @param {*} jsonValue - The JSON value to convert
     * @param {PaymentOverFlowHandleMethod} [defaultValue=null] - Default value if conversion fails
     * @returns {PaymentOverFlowHandleMethod|null} Converted PaymentOverFlowHandleMethod value
     */
    static jsonToPaymentOverFlowHandleMethod(jsonValue, { defaultValue = null } = {}) {
        if (jsonValue == null) {
            return defaultValue;
        } else {
            let retValue = defaultValue;
            try {
                retValue = PaymentOverFlowHandleMethod.fromCode(jsonValue);
            } catch (err) {
                console.log(`Convert jsonToPaymentOverFlowHandleMethod string failed: ${err}`);
            }
            return retValue;
        }
    }

    /**
 * Convert JSON value to Date object
 * @param {*} value - The value to convert (can be string, number, or Date)
 * @param {Date} [defaultValue] - Optional default value if conversion fails
 * @returns {Date} Converted Date object
 */
    static jsonToDateTime(value, defaultValue = null) {
        // Set default to Unix epoch (1970-01-01) if not provided
        const defaultDate = new Date();
        defaultValue = defaultValue || defaultDate;

        if (value == null) {
            return defaultValue;
        }

        try {
            // Handle multiple input types:
            // - Already a Date object
            if (value instanceof Date) {
                return new Date(value.getTime());
            }
            // - Timestamp (number)
            if (typeof value === 'number') {
                return new Date(value);
            }
            // - ISO string
            const parsedDate = new Date(value.toString());
            // Validate the parsed date
            if (!isNaN(parsedDate.getTime())) {
                return parsedDate;
            }
        } catch (err) {
            console.error("Convert jsonToDateTime failed:", err);
        }

        return defaultValue;
    }

    /// 获取单据状态颜色 state CommonOrderStatus
    static getCommonOrderStateColor(state) {
        let color = AppTheme.draftStateColor;
        switch (state.code) {
            //     case CommonOrderStatus.Draft:
            //       color = AppTheme.draftStateColor;
            //       break;
            case CommonOrderStatus.Passed.code:
                color = AppTheme.reviewedStateColor;
                break;
            case CommonOrderStatus.WaitReview.code:
                color = AppTheme.waitReviewSateColor;
                break;
            default:
                color = AppTheme.draftStateColor;
                break;
        }

        return color;
    }

    // state ProgressState
    static getProgressStateColor(state) {
        let ret = AppTheme.noActionColor;
        switch (state.code) {
            case ProgressState.None.code:
                ret = AppTheme.noActionColor;
                break;
            case ProgressState.PartDone.code:
                ret = AppTheme.partActionColor;
                break;
            case ProgressState.AllDone.code:
                ret = AppTheme.fullActionColor;
                break;
            default:
                ret = AppTheme.noActionColor;
                break;
        }

        return ret;
    }

    /// 待入库状态名称
    // state ProgressState, type InventoryInOutType
    static getPendingInventoryStateName(
        state, type) {
        let operateStr = type == InventoryInOutType.In ? "入库" : "出库";

        let ret = "";
        switch (state.code) {
            case ProgressState.None.code:
                ret = "未" + operateStr;
                break;
            case ProgressState.PartDone.code:
                ret = "部分" + operateStr;
                break;
            case ProgressState.AllDone.code:
                ret = operateStr + "完成";
                break;
            default:
                ret = "未知";
                break;
        }

        return ret;
    }
    /**
 * Get color for order status
 * @param {CommonOrderStatus} state - The order status 
 * @returns {Color} The color corresponding to the status
 */
    static getCommonOrderStateColor(state) {
        let color = AppTheme.draftStateColor;

        if (state.code === CommonOrderStatus.Passed.code) {
            color = AppTheme.reviewedStateColor;
        } else if (state.code === CommonOrderStatus.WaitReview.code) {
            color = AppTheme.waitReviewSateColor;
        } else {
            color = AppTheme.draftStateColor;
        }

        return color;
    }



    // todo 上传文件
    static async uploadFile(filePath) {
        // 注意要用apireturn 结构封装
        uploadImgFile(filePath);
    }

    /// 启停用状态
    static getEnableString(state) {
        return state ? "启用" : "停用";
    }

}